﻿/*******************************************************************************************************************************************
Modification History:
********************************************************************************************************************************************
Date		Author		    Description
********************************************************************************************************************************************
05/07/2011	Brian Kuhn	    Created MessageReceivedEventArgs class
*******************************************************************************************************************************************/
using System;
using System.Runtime.Serialization;

namespace Concise
{
    /// <summary>
    /// Provides data for the <see cref="IServiceBus.MessageReceived"/> event.
    /// </summary>
    [DataContract()]
    public class MessageReceivedEventArgs : EventArgs
    {
        //=======================================================================================================
        //  Constructors
        //=======================================================================================================
        #region MessageReceivedEventArgs()
        /// <summary>
        /// Initializes a new instance of the <see cref="MessageReceivedEventArgs"/> class.
        /// </summary>
        protected MessageReceivedEventArgs() : base()
        {

        }
        #endregion

        #region MessageReceivedEventArgs(object message, IMessageContext context)
        /// <summary>
        /// Initializes a new instance of the <see cref="MessageReceivedEventArgs"/> class 
        /// using the specified <paramref name="message"/> and <paramref name="context"/>.
        /// </summary>
        /// <param name="message">The message that was received.</param>
        /// <param name="context">The context information for the <paramref name="message"/>.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="message"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        public MessageReceivedEventArgs(object message, IMessageContext context) : this()
        {
            this.Message    = message;
            this.Context    = context;
        }
        #endregion

        //=======================================================================================================
        //  Public Properties
        //=======================================================================================================
        #region Context
        /// <summary>
        /// Gets the context information for the message that was received.
        /// </summary>
        /// <value>
        /// A <see cref="IMessageContext"/> that provides context information for the <see cref="Message"/> that was received. 
        /// The default value is a <see langword="null"/> reference (Nothing in Visual Basic).
        /// </value>
        [DataMember()]
        public IMessageContext Context
        {
            get
            {
                return _eventArgsContext;
            }

            protected set
            {
                if (!Object.Equals(_eventArgsContext, value))
                {
                    _eventArgsContext = value;
                }
            }
        }
        private IMessageContext _eventArgsContext;
        #endregion

        #region Message
        /// <summary>
        /// Gets the message that was received.
        /// </summary>
        /// <value>
        /// The message that was received. The default value is a <see langword="null"/> reference (Nothing in Visual Basic).
        /// </value>
        /// <exception cref="ArgumentNullException">The <paramref name="value"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        [DataMember()]
        public object Message
        {
            get
            {
                return _eventArgsMessage;
            }

            protected set
            {
                Guard.AgainstNullReference(value, "value");

                if (!Object.Equals(_eventArgsMessage, value))
                {
                    _eventArgsMessage = value;
                }
            }
        }
        private object _eventArgsMessage;
        #endregion

        //=======================================================================================================
        //  Public Methods
        //=======================================================================================================
        #region As<T>()
        /// <summary>
        /// Returns the <see cref="Message"/> as an instance of type <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The type to convert the <see cref="Message"/> to.</typeparam>
        /// <returns>
        /// An object of type <typeparamref name="T"/> that represents the <see cref="Message"/>. 
        /// If the <see cref="Message"/> cannot be converted to a type of <typeparamref name="T"/>, 
        /// returns the <see langword="default"/> of type <typeparamref name="T"/>.
        /// </returns>
        public T As<T>()
        {
            T result    = default(T);

            try
            {
                result  = (T)this.Message;
            }
            catch(InvalidCastException)
            {
                result  = default(T);
            }
            catch (NullReferenceException)
            {
                result  = default(T);
            }

            return result;
        }
        #endregion
    }
}
